#include "widget.h"
#include "ui_widget.h"
#include <QSerialPortInfo>
#include <QDebug>
#include <QMessageBox>

Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);
    this->setLayout(ui->gridLayoutGlobal);      //让界面随着窗口变幻大小
    ui->btnSendContex->setEnabled(false);       //刚打开串口，发送按钮是失效的
    serialPort = new QSerialPort(this);         //创建一个QSerialPort对象，将指针赋值给serialPort变量

    connect(serialPort,&QSerialPort::readyRead,this,&Widget::on_SerialData_readyToRead);        //连接函数，当接收数据可读时


    QList<QSerialPortInfo> serialList= QSerialPortInfo::availablePorts();     //获取系统中可用的串口
    for(QSerialPortInfo serialInfo : serialList)        //遍历所有可用串口
    {
        qDebug() <<  serialInfo.portName();
        ui->comboBox_serialnum->addItem(serialInfo.portName());     //将serialInfo对象所代表的串口添加到UI中
    }

}

Widget::~Widget()
{
    delete ui;
}

void Widget::on_btncloseorOpen_clicked(bool checked)
{
    if(!checked)
    {
        //1.选择端口号
        serialPort->setPortName(ui->comboBox_serialnum->currentText());     //获取串口，把串口显示到文本上
        //2.配置波特率
        serialPort->setBaudRate(ui->comboBox_boautrate->currentText().toInt());  //显示波特率，转整型
        //3.配置数据位
        serialPort->setDataBits(QSerialPort::DataBits(ui->comboBox_databit->currentText().toInt()));    //显示波特率，转整型
        //4.配置校验位
        switch (ui->comboBox_jiaoyan->currentText().toInt())       //用户选择校验位，并转为整型
        {
        case 0:
            serialPort->setParity(QSerialPort::NoParity);       //无奇偶校验
            break;
        case 1:
            serialPort->setParity(QSerialPort::EvenParity);     //偶校验
            break;
        case 2:
            serialPort->setParity(QSerialPort::MarkParity);     //标记校验
            break;
        case 3:
            serialPort->setParity(QSerialPort::OddParity);      //奇校验
            break;
        case 4:
            serialPort->setParity(QSerialPort::SpaceParity);    //空格校验
            break;
        default:
            serialPort->setParity(QSerialPort::UnknownParity);  //未知校验
            break;
        }
        //5.配置停止位
        serialPort->setStopBits(QSerialPort::StopBits(ui->comboBox_stopbit->currentText().toInt()));      //显示停止位，转整型
        //6.流控
        if(ui->comboBox_fluidCon->currentText() == "None")      //用户选择了None
        {
            serialPort->setFlowControl(QSerialPort::NoFlowControl);     //执行，无流控
        }
        //7.打开串口
        if(serialPort->open(QIODevice::ReadWrite))
        {
            qDebug() << "serial open success";
            ui->comboBox_databit->setEnabled(false);    //成功打开串口，这些按钮就失效
            ui->comboBox_fluidCon->setEnabled(false);
            ui->comboBox_jiaoyan->setEnabled(false);
            ui->comboBox_stopbit->setEnabled(false);
            ui->comboBox_boautrate->setEnabled(false);
            ui->comboBox_serialnum->setEnabled(false);
            ui->btncloseorOpen->setText("关闭串口");
            ui->btnSendContex->setEnabled(true);
        }
        else
        {
            QMessageBox msgBox;         //弹窗
            msgBox.setWindowTitle("打开串口错误");
            msgBox.setText("打开失败，串口可能被占用或已拔出");
            msgBox.exec();
        }

    }
    else
    {
        serialPort->close();
        ui->btncloseorOpen->setText("打开串口");
        ui->comboBox_databit->setEnabled(true);    //没有打开串口，这些按钮都是生效的
        ui->comboBox_fluidCon->setEnabled(true);
        ui->comboBox_jiaoyan->setEnabled(true);
        ui->comboBox_stopbit->setEnabled(true);
        ui->comboBox_boautrate->setEnabled(true);
        ui->comboBox_serialnum->setEnabled(true);
        serialStatus = false;
        ui->btnSendContex->setEnabled(false);      //没有打开串口，发送按钮失效
    }


}

void Widget::on_btnSendContex_clicked()
{
    int writeCnt = 0;
    const char* sendData = ui->lineEditSendContex->text().toStdString().c_str();    //把发送文本转换为C字符串
    writeCnt = serialPort->write(sendData);     //返回实际写入的字节数
    if(writeCnt == -1)
    {
        ui->labelSendStatus->setText("Send Error!");       //返回字节数失败，表示发送错误
    }
    else
    {
        writeCntTotal += writeCnt;          //写入成功，将字节数累加到writeCntTotal变量上
    }
    qDebug() << "SendOK" << sendData;       //输出SendOK和sendData里面的内容
    ui->labelSendStatus->setText("Send OK!");       //把发送状态改为Send OK
    if(strcmp(sendData,SendBack.toStdString().c_str()) != 0)    //比较sendData和上一次输出的数据是否相同
    {
        ui->textEditRecord->append(sendData);       //不同则在textEditRecord里追加数据
        SendBack = QString(sendData);               //将数据转成QString类型，以便下次使用
    }

}

//读取发送的数据
void Widget::on_SerialData_readyToRead()
{
    QString revMessage = serialPort->readAll();     //读取数据存于revMessage
    qDebug() << "getMessage:" << revMessage;
    ui->textEditRev->append(revMessage);            //把数据显示到控件textEditRev上
}
